/** 枚举时间梯度，减少计算压力 */
export const enum TimeStair {
    /** 毫秒 */
    ms = 1,
    /** 秒 */
    s = 1000,
    /** 分 */
    m = 60000,
    /** 小时 */
    h = 3600000,
    /** 天 */
    d = 86400000
}

/** 格式化一些样式 */
export default class FormatExt {

    /**
     * 数字前部补0对齐
     * 备注：(浮点数的小数点，也算作1位)
     * @param num 原始数值
     * @param len 需要对齐的位数
     */
    static alignZero(num: number, len: number): string {
        return String(num).padStart(len, '0');
    }

    /**
     * 格式化日期字符串
     * @param time 时间戳(ms)
     * @param format 格式化样式
     * @returns
     */
    static formatDate(time: string | number | null, format: string = 'YYYY-MM-DD HH:mm:ss'): string {
        const date = !time ? new Date() : new Date(time);
        if (!format) return date.toLocaleString();

        const obj = {
            YYYY: date.getFullYear(),
            MM: String(date.getMonth() + 1).padStart(2, '0'),
            DD: String(date.getDate()).padStart(2, '0'),
            HH: String(date.getHours()).padStart(2, '0'),
            mm: String(date.getMinutes()).padStart(2, '0'),
            ss: String(date.getSeconds()).padStart(2, '0'),
            SSS: String(date.getMilliseconds()).padStart(3, '0'),
            YY: String(date.getFullYear()).slice(-2),
            M: date.getMonth() + 1,
            D: date.getDate(),
            H: date.getHours(),
            m: date.getMinutes(),
            s: date.getSeconds(),
        };
        return Object.entries(obj).reduce((result, [key, value]) =>
            result.replace(key, String(value)), format);
    }

    /**
     * 格式化数值为时间单位
     */
    private static formatTimeUnit(value: number): { padded: string, raw: number } {
        return {
            padded: String(value).padStart(2, '0'),
            raw: value
        };
    }

    /**
     * 格式化倒计时格式
     */
    static formatTimer(leftMSec: number, format: string = "HH:mm:ss"): string {
        const hou = Math.floor(leftMSec / TimeStair.h);
        const min = Math.floor((leftMSec % TimeStair.h) / TimeStair.m);
        const sec = Math.floor((leftMSec % TimeStair.m) / TimeStair.s);
        const ms = leftMSec % TimeStair.s;

        const timeUnits = {
            HH: this.formatTimeUnit(hou),
            H: { padded: String(hou), raw: hou },
            mm: this.formatTimeUnit(min),
            m: { padded: String(min), raw: min },
            ss: this.formatTimeUnit(sec),
            s: { padded: String(sec), raw: sec },
            SSS: this.formatTimeUnit(ms),
        };

        return Object.entries(timeUnits).reduce((result, [key, value]) => 
            result.replace(key, value.padded), format);
    }
}